package org.gitman.agentplatform.agent.impl.malicious;

import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Stack;

import org.gitman.agentplatform.agent.api.AgentInfo;
import org.gitman.agentplatform.agent.api.AgentPlan;
import org.gitman.agentplatform.agent.api.utils.AbstractAgent;
import org.gitman.agentplatform.model.Vertex;
import org.gitman.agentplatform.model.utils.GraphTools;

public class MaliciousAgent extends AbstractAgent{
	Stack<Integer> shorthestPath =null;
	private Random rand;
	
	
	public MaliciousAgent() {
		rand = new Random(Calendar.getInstance().getTimeInMillis()); 
	}
	
	
	@Override
	public Integer getStep(Collection<AgentInfo> agentsInRange) {
		updatePlan(agentsInRange);
		if(shorthestPath.size() > 0){
			return shorthestPath.peek();
		}else{
			return null;
		}
	}
	@Override
	public AgentPlan getPlan(int depth, Collection<AgentInfo> agentsInRange) {
		Integer [] tab = generatePlan(depth);
		HashMap<Integer[],Double> map = new HashMap<Integer[], Double>();
		map.put(tab, 1.0);
		return new AgentPlan(map);
	}
	private Integer[] generatePlan(int depth) {
		int size = depth;
		if(depth > Math.sqrt(graph.getVertices().size())){
			size = 	shorthestPath != null? shorthestPath.size() +1 : 1;
		}		 
		Integer [] tab = new Integer[size];
		Vertex v = graph.getVertexByID(agentInfo.getCurrentVertexID());
		for(int i =0;i<size;i++){
			Collection<Vertex> neighbours = v.getNeighbours();
			LinkedList<Vertex> list = new LinkedList<Vertex>(neighbours);
			if(!list.isEmpty()){
				int index = rand.nextInt(list.size());
				v = list.get(index);
			}
			tab[i] = v.getId();			
		}		
		return tab;
	}
	private void updatePlan(Collection<AgentInfo> agents) {
		Map<Integer, Set<Integer>> map = new HashMap<Integer, Set<Integer>>();
		Set<Integer> list = new HashSet<Integer>();
		for(AgentInfo info : agents){
			list.add(info.getCurrentVertexID());
		}
		map.put(1, list);
		shorthestPath = GraphTools.getShorthestPath(graph, agentInfo.getCurrentVertexID(), agentInfo.getEndVertexID(),map);
		if(shorthestPath == null){
			shorthestPath = new Stack<Integer>();
		}
		while(shorthestPath.size() > 0 && agentInfo.getCurrentVertexID().equals(shorthestPath.peek())){
			shorthestPath.pop();
		}
	}
}
